package com.ruoyi.shop.member.service.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.shop.member.mapper.ShopConfigSignMapper;
import com.ruoyi.shop.member.mapper.ShopMemberGrowthMapper;
import com.ruoyi.shop.member.mapper.ShopMemberMapper;
import com.ruoyi.shop.member.mapper.ShopMemberPointMapper;
import com.ruoyi.shop.member.mapper.ShopMemberSignMapper;
import com.ruoyi.shop.member.service.IShopMemberSignService;
import com.ruoyi.shop.member.vo.ShopConfigSignVo;
import com.ruoyi.shop.member.vo.ShopMemberSignVo;
import com.ruoyi.shop.member.vo.ShopMemberVo;
import com.ruoyi.shop.common.constant.ShopConstants;
import com.ruoyi.shop.common.exception.ShopException;
import com.ruoyi.shop.member.domain.ShopMember;
import com.ruoyi.shop.member.domain.ShopMemberGrowth;
import com.ruoyi.shop.member.domain.ShopMemberPoint;
import com.ruoyi.shop.member.domain.ShopMemberSign;

/**
 * 会员签到Mapper接口
 * 
 * @author xuxiang
 */
@Service
public class ShopMemberSignServiceImpl implements IShopMemberSignService {
	@Autowired
	private ShopMemberMapper shopMemberMapper;
	@Autowired
	private ShopMemberSignMapper shopMemberSignMapper;
	@Autowired
	private ShopMemberPointMapper shopMemberPointMapper;
	@Autowired
	private ShopMemberGrowthMapper shopMemberGrowthMapper;
	@Autowired
	private ShopConfigSignMapper shopConfigSignMapper;

	/**
	 * 查询会员签到记录列表
	 * 
	 * @param memberId 会员Id
	 * @return 会员签到记录
	 */
	@Override
	public List<ShopMemberSign> selectSignByMemberId(Long memberId) {
		return shopMemberSignMapper.selectSignByMemberId(memberId);
	}

	/**
	 * 查询会员签到记录列表
	 * 
	 * @param signVo 会员签到记录
	 * @return 会员签到记录
	 */
	@Override
	public List<ShopMemberSignVo> selectSignList(ShopMemberSignVo signVo) {
		return shopMemberSignMapper.selectSignList(signVo);
	}

	/**
	 * 新增会员签到
	 * 
	 * @param shopMemberSign 会员签到
	 * @return 结果
	 */
	@Override
	public int insertSign(ShopMemberSign shopMemberSign) {
		shopMemberSign.setCreateTime(DateUtils.getNowDate());
		return shopMemberSignMapper.insertSign(shopMemberSign);
	}

	/**
	 * 获取签到配置
	 * 
	 * @param memberId
	 * @return
	 */
	@Override
	public List<ShopConfigSignVo> selectSignConfig() {
		return shopConfigSignMapper.selectConfigList();
	}

	/**
	 * 会员签到
	 * 
	 * @return 结果
	 */
	@Override
	@Transactional
	public ShopConfigSignVo signIn(Long memberId) {
		Map<Integer, ShopConfigSignVo> signConfigMap = this.getSignConfgMap();
		if (StringUtils.isNull(signConfigMap) || signConfigMap.isEmpty()) {
			throw new ShopException("请先配置签到天数");
		}
		ShopMember shopMember = shopMemberMapper.selectMemberById(memberId);
		ShopMemberSign lastSign = shopMemberSignMapper.selectLastSign(memberId);
		Integer signDay = 1;
		BigDecimal totalPoint = BigDecimal.ZERO;
		BigDecimal totalGrowth = BigDecimal.ZERO;
		// 第一次签到
		if (StringUtils.isNull(lastSign)) {
			ShopConfigSignVo signconfig = signConfigMap.get(1);
			if (StringUtils.isNotNull(signconfig)) {
				// 积分奖励
				if (StringUtils.isNotNull(signconfig) && signconfig.getIsPoint().equals(ShopConstants.YES)) {
					totalPoint = totalPoint.add(signconfig.getPoint());
				}
				// 成长值奖励
				if (StringUtils.isNotNull(signconfig) && signconfig.getIsPoint().equals(ShopConstants.YES)) {
					totalGrowth = totalGrowth.add(signconfig.getGrowth());
				}
				String title = "每日签到奖励";
				// 插入签到记录
				ShopMemberSign signRecord = new ShopMemberSign();
				signRecord.setTitle(title);
				signRecord.setMemberId(memberId);
				signRecord.setSignDate(DateUtils.getDate());
				signRecord.setCreateTime(DateUtils.getNowDate());
				signRecord.setSignDays(signDay);
				signRecord.setPoint(totalPoint);
				signRecord.setGrowth(totalGrowth);
				shopMemberSignMapper.insertSign(signRecord);
				// 开启积分奖励-插入积分记录
				if (signconfig.getIsPoint().equals(ShopConstants.YES)) {
					ShopMemberPoint pointRecord = new ShopMemberPoint();
					pointRecord.setMemberId(memberId);
					pointRecord.setTitle(title + "积分");
					pointRecord.setDataType(ShopConstants.SHOP_BUSINESS_TYPE_SIGN_IN);// 签到
					pointRecord.setChangeType(ShopConstants.SHOP_DATA_CHANGE_TYPE_ADD);// 变动方向-增加
					pointRecord.setValue(signconfig.getPoint());// 变动积分
					pointRecord.setBalance(shopMember.getPoint().add(totalPoint));
					pointRecord.setCreateTime(DateUtils.getNowDate());
					pointRecord.setOperType(0);// 会员用户
					shopMemberPointMapper.insertPoint(pointRecord);
				}
				// 开启成长值奖励-插入成长值记录
				if (signconfig.getIsGrowth().equals(ShopConstants.YES)) {
					ShopMemberGrowth growthRecord = new ShopMemberGrowth();
					growthRecord.setMemberId(memberId);
					growthRecord.setTitle(title + "成长值");
					growthRecord.setDataType(ShopConstants.SHOP_BUSINESS_TYPE_SIGN_IN);// 签到
					growthRecord.setChangeType(ShopConstants.SHOP_DATA_CHANGE_TYPE_ADD);// 变动方向-增加
					growthRecord.setValue(signconfig.getGrowth());// 变动积分
					growthRecord.setBalance(shopMember.getGrowth().add(totalPoint));
					growthRecord.setCreateTime(DateUtils.getNowDate());
					growthRecord.setOperType(0);// 会员用户
					shopMemberGrowthMapper.insertGrowth(growthRecord);
				}

			}
		}
		// 有签到记录
		else {
			signDay = lastSign.getSignDays() + 1;
			
			ShopConfigSignVo signconfig = signConfigMap.get(signDay);
			if (StringUtils.isNotNull(signconfig)) {
				// 积分奖励
				if (StringUtils.isNotNull(signconfig) && signconfig.getIsPoint() == 0) {
					totalPoint = totalPoint.add(signconfig.getPoint());
				}
				// 成长值奖励
				if (StringUtils.isNotNull(signconfig) && signconfig.getIsGrowth() == 0) {
					totalGrowth = totalGrowth.add(signconfig.getGrowth());
				}
				String title = "每日签到奖励";
				if (signDay == signConfigMap.size()) {
					title = "连续签到奖励";
				}
				ShopMemberSign signRecord = new ShopMemberSign();
				signRecord.setTitle(title);
				signRecord.setMemberId(memberId);
				signRecord.setSignDate(DateUtils.getDate());
				signRecord.setCreateTime(DateUtils.getNowDate());
				signRecord.setSignDays(signDay);
				signRecord.setPoint(totalPoint);
				signRecord.setGrowth(totalGrowth);
				shopMemberSignMapper.insertSign(signRecord);
				// 开启积分奖励-插入积分记录
				if (signconfig.getIsPoint().equals(ShopConstants.YES)) {
					ShopMemberPoint pointRecord = new ShopMemberPoint();
					pointRecord.setMemberId(memberId);
					pointRecord.setTitle(title);
					pointRecord.setDataType(ShopConstants.SHOP_BUSINESS_TYPE_SIGN_IN);// 签到
					pointRecord.setChangeType(ShopConstants.SHOP_DATA_CHANGE_TYPE_ADD);// 变动方向-增加
					pointRecord.setValue(signconfig.getPoint());// 变动积分
					pointRecord.setBalance(shopMember.getPoint().add(totalPoint));
					pointRecord.setCreateTime(DateUtils.getNowDate());
					pointRecord.setOperType(0);// 会员用户
					shopMemberPointMapper.insertPoint(pointRecord);
				}
				// 开启成长值奖励-插入成长值记录
				if (signconfig.getIsGrowth().equals(ShopConstants.YES)) {
					ShopMemberGrowth growthRecord = new ShopMemberGrowth();
					growthRecord.setMemberId(memberId);
					growthRecord.setTitle(title);
					growthRecord.setDataType(ShopConstants.SHOP_BUSINESS_TYPE_SIGN_IN);// 签到
					growthRecord.setChangeType(ShopConstants.SHOP_DATA_CHANGE_TYPE_ADD);// 变动方向-增加
					growthRecord.setValue(signconfig.getGrowth());// 变动积分
					growthRecord.setBalance(shopMember.getGrowth().add(totalPoint));
					growthRecord.setCreateTime(DateUtils.getNowDate());
					growthRecord.setOperType(0);// 会员用户
					shopMemberGrowthMapper.insertGrowth(growthRecord);
				}
			}
		}

		/*** 钱包余额、经验值...奖励 自由扩展 *****/

		// 更新会员业务数据
		shopMember.setPoint(shopMember.getPoint().add(totalPoint));// 增加积分
		shopMember.setGrowth(shopMember.getGrowth().add(totalGrowth));// 增加成长值
		shopMemberMapper.updateMemberData(shopMember);
		return null;
	}

	/**
	 * 查询今日是否签到(0是1否)
	 * 
	 * @param memberId
	 * @return
	 */
	@Override
	public int getIsTodaySign(Long memberId) {
		ShopMemberSign params = new ShopMemberSign();
		params.setMemberId(memberId);
		params.setSignDate(DateUtils.getDate());
		if (shopMemberSignMapper.selecSignByDate(params) > 0) {
			return 0;
		}
		return 1;
	}

	/**
	 * 查询昨日是否签到
	 * 
	 * @param memberId
	 * @return
	 */
	public int getIsYesterdaySign(Long memberId) {
		ShopMemberSign params = new ShopMemberSign();
		params.setMemberId(memberId);
		params.setSignDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, DateUtils.addDays(new Date(), -1)));
		if (shopMemberSignMapper.selecSignByDate(params) > 0) {
			return 0;
		}
		return 1;
	}

	/**
	 * 获取签到会员数据
	 * 
	 * @param memberId
	 * @return
	 */
	@Override
	public ShopMemberVo getSignUser(Long memberId) {
		Map<Integer, ShopConfigSignVo> signConfigMap = this.getSignConfgMap();
		ShopMemberSign lastSign = shopMemberSignMapper.selectLastSign(memberId);
		// 连续签到天数
		int signDays = StringUtils.isNull(lastSign) ? 0 : lastSign.getSignDays();
		// 昨日没签到或签到天数等于配置天数，更新签到记录为签到周期无效状态
		if ((this.getIsYesterdaySign(memberId) == 1) || (signDays == signConfigMap.size())) {
			ShopMemberSign params = new ShopMemberSign();
			params.setUpdateTime(DateUtils.getNowDate());
			params.setMemberId(memberId);
			params.setStatus(ShopConstants.NO);// 无效
			params.setSignDate(DateUtils.getDate());
			shopMemberSignMapper.updateSign(params);
		}
		ShopMember shopMember = shopMemberMapper.selectMemberById(memberId);
		ShopMemberVo memberVo = new ShopMemberVo();
		BeanUtils.copyBeanProp(memberVo, shopMember);
		// 当日是否签到
		memberVo.setIsTodaySign(getIsTodaySign(memberId));
		// 连续签到天数
		lastSign = shopMemberSignMapper.selectLastSign(memberId);
		memberVo.setSignDays(StringUtils.isNull(lastSign) ? 0 : lastSign.getSignDays());
		// 累计签到天数
		memberVo.setSumSignDays(shopMemberSignMapper.selectSumByMemberId(memberId));
		return memberVo;
	}
	
	/**
	 * 签到配置List转Map
	 * 
	 * @return
	 */
	private Map<Integer, ShopConfigSignVo> getSignConfgMap() {
		List<ShopConfigSignVo> configs =shopConfigSignMapper.selectConfigList();
		Map<Integer, ShopConfigSignVo> map = new LinkedHashMap<>();
		for (ShopConfigSignVo config : configs) {
			map.put(config.getDayNum(), config);
		}
		return map;
	}


}